const webpack = require('webpack');
const path = require('path');
const globalConfig = require('./src/config.js');

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const autoprefixer = require('autoprefixer');
const CleanWebpackPlugin = require('clean-webpack-plugin'); //引入清除文件插件

// bundle split, 尝试把这些比较独立的库单独放在一个js文件中
// 注意只有真正"公用"的库才能放这里, 否则会有各种奇怪的问题
// 而且必须在bundle.js之前加载
const vendorLibs = ['react', 'react-router',
  'redux', 'react-redux', 'redux-logger', 'redux-thunk', 'redux-promise',
  'superagent',
];

// 像素适配转换插件配置
const postcssOpts = {
  ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
  plugins: () => [
    autoprefixer({
      browsers: ['last 2 versions', 'Firefox ESR', '> 1%', 'ie >= 8', 'iOS >= 8', 'Android >= 4'],
    }),
    // pxtorem({rootValue: 100, propWhiteList: []}) // 是否开启像素转换 px=>rem
  ],
};

module.exports = {
  mode: "production",

  devtool: 'cheap-module-source-map',

  entry: [
    // 'babel-polyfill',// 可以使用完整的ES6特性, 大概增加100KB (transform-runtime已经自动引入)
    './src/index.js',
  ],

  output: {
    path: path.join(__dirname, globalConfig.outputPath + '/dist'), // 用来存放打包后文件的输出目录
    publicPath: '/dist/', // 指定资源文件引用的目录
    filename: 'bundle.min.js',
    chunkFilename: '[name].[chunkhash].chunk.js',
  },

  resolve: {
    modules: [ // 告诉 webpack 解析模块时应该搜索的目录
      "node_modules",
      path.resolve(__dirname, "src")
    ],
    extensions: ['*', '.js', '.jsx'], // 自动解析确定的扩展
    // 定义路径别名
    alias: {
      Components: path.resolve("src/components"),
      Pages: path.resolve("src/pages"),
      Utils: path.resolve("src/utils"),
      Less: path.resolve("src/statics/less"),
      Image: path.resolve("src/statics/image"),
    }
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
          plugins: [
            ["transform-runtime", {polyfill: true}],
            ['import', [{libraryName: 'antd-mobile', style: true}]],
          ],
          presets: ['latest', 'stage-0', 'react']
        },
      },
      {
        test: /\.css$/,
        // use: ['style-loader', 'css-loader', {loader: 'postcss-loader', options: postcssOpts}]
        use: [
          {
            loader: MiniCssExtractPlugin.loader // style-loader无需使用
          },
          'css-loader', {loader: 'postcss-loader', options: postcssOpts}
        ]
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          'css-loader',
          {loader: 'postcss-loader', options: postcssOpts},
          {
            loader: "less-loader",
            options: {
              javascriptEnabled: true
            }
          }
        ]
      },
      {
        test: /\.(svg|eot|ttf|woff)$/,
        use: ['file-loader']
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10000
            }
          }
        ]
      }
    ]
  },

  performance: { // 性能配置
    hints: false,
    maxEntrypointSize: 512000,
    maxAssetSize: 512000
  },

  optimization: {
    // 代码压缩
    minimizer: [
      new UglifyJsPlugin({
        uglifyOptions: {
          sourceMap: true,
          parallel: 4, // 并发运行数
          warnings: false,
          output: {
            // 最紧凑的输出
            beautify: false,
            // 删除所有的注释
            comments: false,
          },
          compress: {
            warnings: false,// 在UglifyJs删除没有用到的代码时不输出警告
            drop_console: true,// 删除所有的 `console` 语句，可以兼容ie浏览器
            drop_debugger: true,
            unused: false,
          },
          toplevel: false,
          nameCache: null,
          ie8: false,
          keep_classnames: undefined,
          keep_fnames: false,
          safari10: false,
        }
      })
    ],
    // 抽离公共js
    splitChunks: {
      chunks: 'all', // 必须三选一： "initial" | "all" | "async"(默认就是异步)
      minSize: 30000,
      minChunks: 1,
      name: true,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      cacheGroups: { // 这里开始设置缓存的 chunks
        commons: {
          chunks: 'initial',
          minChunks: 2,
          maxInitialRequests: 5,
          minSize: 0
        },
        // vendors: { // 将第三方模块提取出来
        //   test: /[\\/]node_modules[\\/]/,
        //   chunks: 'initial',
        //   name: 'vendor', // 要缓存的 分隔出来的 chunk 名称
        //   filename: '[name].min.js',
        //   priority: -10,
        //   enforce: true,
        // },
        vendors: {
          // 这个函数决定哪些模块会被放到vender.min.js中
          test: (module) => {
            // 得到资源路径
            var resource = module.resource;
            if (!resource)
              return false;
            for (var libName of vendorLibs) {
              if (resource.indexOf(path.resolve(__dirname, 'node_modules', libName)) >= 0)
                return true;
            }
            return false;
          },
          chunks: 'initial',
          name: 'vendor', // 要缓存的 分隔出来的 chunk 名称
          filename: '[name].min.js',
          enforce: true,
          priority: 1,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        }
      }
    },
    // 将webpack运行时生成代码打包到runtime.js
    runtimeChunk: true
  },

  plugins: [
    new CleanWebpackPlugin(),

    new HtmlWebpackPlugin({
      template: 'index.html',// 模板文件
      filename: '../index.html',// 入口文件
      title: globalConfig.name,
      favIcon: globalConfig.favicon,
      hash: true,  // 引入js/css的时候加个hash, 防止cdn的缓存问题
      minify: {removeComments: true, collapseWhitespace: true},
    }),

    new webpack.optimize.AggressiveMergingPlugin(),
    // 允许错误不打断程序
    new webpack.NoEmitOnErrorsPlugin(),

    // css单独抽出来
    new MiniCssExtractPlugin({
      filename: 'bundle.min.css'
    }),
    // 压缩成gzip格式  nginx需要配置支持
    new CompressionPlugin(),

    // 配置全局常量
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
      __DEV__: JSON.stringify(JSON.parse(process.env.NODE_ENV === 'production' ? 'false' : 'true')),
    }),
  ],
};